import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class AnimatedGraphics extends JComponent implements ActionListener {
	public static int REFRESH = 1;
	public static int TIMER = 120;
    Color startColor = new Color(20,20,0);	// where we start
    Color endColor = Color.BLUE;         // where we end
    Color currentColor = startColor;
    int animationDuration = 2000; 	// each animation will take 2 seconds
    long animStartTime;			// start time for each animation
    public ParticleBox[] numNums;
    Integer[] allInts;
    BufferedReader sorted;
    public int numNumWidth;
    
    /**
     * Set up and start the timer
     */
    public AnimatedGraphics(String initialFile, String sortedFile) {
		allInts = ArrayGetter.getIntegerArray(initialFile);
		numNums = new ParticleBox[allInts.length];
		try {
			sorted = new BufferedReader(new FileReader(sortedFile));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		
        Timer timer = new Timer(REFRESH, this);
        // initial delay while window gets set up
        timer.setInitialDelay(1000);
        animStartTime = 1000 + System.nanoTime() / 1000000;
        timer.start();
    }
    
    public void constructNums(){		
		/*
		 * Construct numNums
		 */
		numNumWidth = (getWidth()/numNums.length);
		for(int i=0;i<allInts.length;i++){
			int x = (numNumWidth)*i;
			int y = getHeight();
			numNums[i] = new ParticleBox(numNumWidth,x,y,allInts[i],allInts.length);
		}
    }
    
    /**
     * Erase to the background color and fill an oval with the current
     * color (which is being animated elsewhere)
     */
    public void paintComponent(Graphics g) {
    	g.setColor(new Color(255,255,255));
    	g.fillRect(0, 0, getWidth(), getHeight());
    	for(int i=0;i<numNums.length;i++){
    		numNums[i].draw(g);
    	}
    }
    
    /**
     * Callback from the Swing Timer. Calculate the fraction elapsed of
     * our desired animation duration and interpolate between our start and
     * end colors accordingly.
     */
    public void actionPerformed(ActionEvent ae) {  
    	long currTime = System.nanoTime() / 1000000;
    	if(currTime - animStartTime > TIMER){
    		/*
    		 * Get all numbers that have been sorted so far and move them to the top of the screen
    		 */
    		try {
				String[] soFarString = sorted.readLine().split(" ");
	    		Integer[] soFar = new Integer[soFarString.length];
	    		/*
	    		 * Create integer array of currently sorted numbers
	    		 */
	    		for(int i=0;i<soFar.length;i++){
	    			int key = Integer.valueOf(soFarString[i]);
	    			ParticleBox curr = ParticleBox.getBoxByNum(i, key, numNums);
	    			curr.move(numNumWidth*i,0,curr.width(),Math.abs(curr.height()));
	    		}
			} catch (IOException e) {
				e.printStackTrace();
			} catch (NullPointerException e){
				
			}
			animStartTime = currTime;
    	}
        repaint();
    }
    
    private static void createAndShowGUI() {    
        JFrame f = new JFrame("Animated Graphics");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(1280,1024);
        AnimatedGraphics myBlock = new AnimatedGraphics("myNumbers","output.txt");
        f.add(myBlock);
        f.setVisible(true);
        myBlock.constructNums();        
    }
    
    public static void main(String args[]) {
        Runnable doCreateAndShowGUI = new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        };
        SwingUtilities.invokeLater(doCreateAndShowGUI);
    }
}
